﻿#include "mainframe.h"

#ifdef USING_GUI
#include <QMessageBox>
#include <QApplication>
#include <QStandardPaths>
#include <QDir>
#else
#include <QCoreApplication>
#endif

#include <QDomDocument>
#include <QDebug>

#include <CFSPluginContext.h>

#if defined(Q_OS_MAC)
const QString xmlPath ="/../../../../config/MainBasePlugins.xml";
#else
const QString xmlPath ="/../config/MainBasePlugins.xml";
#endif

/**
 * @brief MainFrame::MainFrame
 * 主框架：不做任何业务处理
 */
MainFrame::MainFrame()
{
    //InitFrameWork();
}

MainFrame::~MainFrame()
{
    //    exit(0);
}

//初始化框架系统、并加载基础插件
void MainFrame::InitFrameWork()
{
    //1、初始化框架系统并启动框架
    if(!startPluginFrame())
    {
#ifdef USING_GUI
        qDebug()<<"Init pluginframe failed!";
        QMessageBox msgbox;
        msgbox.setText(tr("Init pluginframe failed!"));
        msgbox.setWindowTitle(tr("error"));
        msgbox.setButtonText(QMessageBox::Ok,tr("ok"));
        msgbox.setIcon(QMessageBox::Critical);
        msgbox.exec();
        exit(0);
#else
        qDebug()<<"Init pluginframe failed!";
        exit(0);
#endif
    }

    //2、解析XML文件获取位置
#ifdef USING_GUI
    QString workfile = QApplication::applicationDirPath();
#else
    QString workfile = QCoreApplication::applicationDirPath();
#endif

    //获取xml文件绝对路径
    QString config = workfile+xmlPath;

    if(!analysisInfo(config))
    {
#ifdef USING_GUI
        qDebug()<<"XML analysisInfo failed!";
        QMessageBox msgbox;
        msgbox.setText(tr("XML analysisInfo failed!"));
        msgbox.setWindowTitle(tr("error"));
        msgbox.setButtonText(QMessageBox::Ok,tr("ok"));
        msgbox.setIcon(QMessageBox::Critical);
        msgbox.exec();
        exit(0);
#else
        qDebug()<<"XML analysisInfo failed!";
        exit(0);
#endif
    }

    //3、加载解析到的基础插件
    if(!loadPlugins(m_listPluginsInfo.at(0).pluginPath))
    {
#ifdef USING_GUI
        qDebug()<<"loading baseplugin failed!";
        QMessageBox msgbox;
        msgbox.setText(tr("Loading baseplugin failed!"));
        msgbox.setWindowTitle(tr("error"));
        msgbox.setButtonText(QMessageBox::Ok,tr("ok"));
        msgbox.setIcon(QMessageBox::Critical);
        msgbox.exec();
        exit(0);
#else
        qDebug()<<"Loading baseplugin failed!";
        exit(0);
#endif
    }
}

//关闭系统：方法一
void MainFrame::closePluginFrame()
{
    if(m_framework.isNull())
    {
        return ;
    }
    CFSPluginContext *pContext = m_framework->getPluginContext();
    QList<QSharedPointer<CFSPlugin> > plugins = pContext->getPlugins();

    foreach(QSharedPointer<CFSPlugin> tmp,plugins)
    {
        if(tmp->getSymbolicName() == "system.plugin")
        {
            continue;
        }
        tmp->uninstall();
    }
    exit(0);
}

//关闭系统：方法二
void MainFrame::closeSystem()
{
    if(m_framework.isNull())
    {
        return ;
    }
    CFSPluginContext *pContext = m_framework->getPluginContext();
    QList<QSharedPointer<CFSPlugin> > plugins = pContext->getPlugins();

    foreach(QSharedPointer<CFSPlugin> tmp,plugins)
    {
        if(tmp->getSymbolicName() == "system.plugin")
        {
            continue;
        }
        tmp->uninstall();
    }
    exit(0);
}

//关闭系统：方法三
void MainFrame::close()
{
    if(m_framework.isNull())
    {
        return ;
    }
    CFSPluginContext *pContext = m_framework->getPluginContext();
    QList<QSharedPointer<CFSPlugin> > plugins = pContext->getPlugins();

    foreach(QSharedPointer<CFSPlugin> tmp,plugins)
    {
        if(tmp->getSymbolicName() == "system.plugin")
        {
            continue;
        }
        tmp->uninstall();
    }
    exit(0);
}

//加载插件
bool MainFrame::loadPlugins(QString pluginPath)
{
    qDebug() << "mainframework : -------------" << pluginPath ;
    if(m_framework.isNull())
    {
        return false;
    }

    CFSPluginContext *pContext = m_framework->getPluginContext();

    for (int i=0;i<m_listPluginsInfo.count();i++)
    {
        try
        {
#ifdef USING_GUI
            QString workfile = QApplication::applicationDirPath();
#else
            QString workfile = QCoreApplication::applicationDirPath();
#endif

#if defined(Q_OS_MAC)
            QString config = workfile+"/../../../plugins"+pluginPath;
            QString tmp=QString("/Users/and/Desktop/ModelDeviceSystem/RUNHOME/dbin5.13.0/plugins")+pluginPath;
            qDebug()<<"config"<<config;
            qDebug()<<"tmp"<<tmp;

            //1、判断文件是否存在
            QFile file(config);
            if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
            {
                qDebug()<<"open file failed:"<<config;
                return false;
            }
            //2、获取文件绝对路径，并打开文件：为解决路径不统一
            QFileInfo info(config);
            QSharedPointer<CFSPlugin> plugin =pContext->installPlugin(QUrl::fromLocalFile(info.absoluteFilePath()));
#else
            QString config = workfile + "/" + m_listPluginsInfo.at(i).pluginPath;
            QSharedPointer<CFSPlugin> plugin = pContext->installPlugin(QUrl::fromLocalFile(config));
#endif
            plugin->start(CFSPlugin::START_TRANSIENT);
        }
        catch (CFSPluginException &e)
        {
            qDebug() <<"failed to loading plugin path:"<< pluginPath <<"error info:"<<e.name();
            return false;
        }
    }
    return true;
}

//启动框架
bool MainFrame::startPluginFrame()
{
    m_framework = m_frameWorkFactory.getFramework();
    try
    {
        // 初始化并启动插件框架
        m_framework->init();
        m_framework->start();
        qDebug() << tr("Plugin Framework start ...");
    }
    catch (const CFSException &e)
    {
        qDebug() << tr("Failed to initialize the Bundle framework: ") << e.what();
        return false;
    }

    //注册服务
    CFSPluginContext * m_pContext = m_framework->getPluginContext();
    if(!m_pContext)
    {
        return false;
    }
    //注册系统基础服务
    m_pContext->registerService<IMainFrameService>(this);
    return true;
}

//解析基础插件信息
bool MainFrame::analysisInfo(QString xmlfile)
{
    m_listPluginsInfo.clear();
    QFile file(xmlfile);

    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug()<<"open file failed:"<<xmlfile;
        return false;
    }

    QDomDocument doc(xmlfile);
    if(!doc.setContent(&file)){
        file.close();
        return false;
    }
    file.close();


    //返回根部节点
    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();
    while (!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement e = node.toElement();
            PLUGIN_INFO xmlinfo;
            if(node.isElement())
            {
                xmlinfo.pluginName=e.attribute("name");

                xmlinfo.pluginPath=e.attribute("path");

            }
            m_listPluginsInfo.append(xmlinfo);
        }
        node = node.nextSibling();
    }
    qDebug()<<"base plugin:"<<m_listPluginsInfo.at(0).pluginPath;
    return true;
}
